package org.zfes.snowier.zbss.xzy.biz.solution.service.impl;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.zfes.snowier.bss.biz.model.AuthDept;
import org.zfes.snowier.bss.biz.model.AuthUser;
import org.zfes.snowier.core.data.DataSet;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.zfes.snowier.core.util.ZBeanUtil;
import org.zfes.snowier.core.util.ZDateUtil;
import org.zfes.snowier.core.util.ZStrUtil;
import org.zfes.snowier.core.util.ZAlert;
import org.zfes.snowier.core.util.ZAssert;
import org.zfes.snowier.core.data.ParamMap;
import com.google.common.collect.Lists;
import org.zfes.snowier.core.data.SelectVo;
import org.zfes.snowier.zbss.xzy.biz.solution.dao.AlgorithmConfigItemMapper;
import org.zfes.snowier.zbss.xzy.biz.solution.model.AlgorithmConfigItem;
import org.zfes.snowier.zbss.xzy.biz.solution.service.IAlgorithmConfigItemService;

import java.util.stream.Stream;
@Service
public class AlgorithmConfigItemServiceImpl implements IAlgorithmConfigItemService{
 	@Autowired
	private AlgorithmConfigItemMapper algorithmConfigItemMapper;
	
 	
 	@Transactional(rollbackFor=Exception.class)
 	@Override
	public void createRootConfigItem(Long algorithmId) {
		
 		AlgorithmConfigItem root = new AlgorithmConfigItem();
 		root.setParentId(0L);
		root.setTreeCode(""+algorithmId+"_");
		root.setCode(""+algorithmId);
		root.setName("配置根节点");//remark
		root.setRemark("配置根节点");
		root.setConfigMode(Byte.valueOf("0"));
		root.setDataType(Byte.valueOf("0"));
		root.setAlgorithmId(algorithmId);
		ZBeanUtil.setCreateInfo(root);
		ZBeanUtil.validateBean(root);
		algorithmConfigItemMapper.insertSelective(root);
	}
 	
 	
	
 	
	@Transactional(rollbackFor=Exception.class)
 	@Override
	public void createAlgorithmConfigItem(AlgorithmConfigItem algorithmConfigItem) {
		ZBeanUtil.setCreateInfo(algorithmConfigItem);
		ZBeanUtil.validateBean(algorithmConfigItem);
		
		Long algorithmId=algorithmConfigItem.getAlgorithmId();
		String code= algorithmConfigItem.getCode();
		
		loadByAlgIdAndCode( algorithmId, code).ifPresent(item->{
			ZAlert.throwSLE("该算法下，配置项编码已经存在");
		});
		
		AlgorithmConfigItem parent = loadAlgorithmConfigItemById(algorithmConfigItem.getParentId()).orElseThrow(()-> ZAlert.newSLE("未查询到父级信息"));
		ZAssert.equals(Byte.valueOf("1"), parent.getStatus(), "父级状态错误");
			
		
		AlgorithmConfigItem maxChild = algorithmConfigItemMapper.selectMaxChild(parent.getId());
		String treeCode="";
		if(maxChild==null) {
			treeCode = parent.getTreeCode()+"000";
			algorithmConfigItem.setTreeCode(treeCode);
		}else {
				String maxChildTreeCode = maxChild.getTreeCode();
				String prefix=ZStrUtil.substring(maxChildTreeCode,0, maxChildTreeCode.length()-3);
				String suffix=ZStrUtil.substring(maxChildTreeCode, maxChildTreeCode.length()-3);
				
				Long next=Long.valueOf(suffix, 36)+1;
				if(next>46656) {
					ZAlert.throwSLE("最大节点数为46656个");
				}
				
				String nextStr=ZStrUtil.autoFillZero(Long.toString(next, 36),3);
				treeCode=prefix+nextStr;
				algorithmConfigItem.setTreeCode(treeCode);
				
			}
		
		algorithmConfigItemMapper.insertSelective(algorithmConfigItem);
	}
	
 	
	@Transactional(rollbackFor=Exception.class)
	@Override
	public void updateAlgorithmConfigItem(AlgorithmConfigItem algorithmConfigItem) {
		ZBeanUtil.setUpdatedInfo(algorithmConfigItem);
		ZBeanUtil.validateBean(algorithmConfigItem);
		
		Long id=algorithmConfigItem.getId();
		Long algorithmId=algorithmConfigItem.getAlgorithmId();
		String code= algorithmConfigItem.getCode();
		
		loadByAlgIdAndCode( algorithmId, code).ifPresent(item->{
			if(!id.equals(item.getId())){
				ZAlert.Error("配置编码已经存在");
			}
		});
		algorithmConfigItemMapper.updateByPrimaryKeySelective(algorithmConfigItem);
	}
	
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<AlgorithmConfigItem> loadAlgorithmConfigItemById(Long id) {
		if(id!=null){
			return Optional.ofNullable(algorithmConfigItemMapper.selectByPrimaryKey(id));
		}
		return Optional.empty();
	}
	
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<AlgorithmConfigItem> loadRootConfigItemById(Long algorithmId) {
		if(algorithmId!=null){
			return Optional.ofNullable(algorithmConfigItemMapper.selectRootConfigItemById(algorithmId));
		}
		return Optional.empty();
	}
	
	
 	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public List<AlgorithmConfigItem> loadByAlgorithmId(Long algorithmId, Byte status) {
 		if(algorithmId==null) {
 			return Lists.newArrayList();
 		}
 		
		return algorithmConfigItemMapper.selectByAlgorithmId(algorithmId,status);
	}
 	
 	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public List<AlgorithmConfigItem> loadChildrenByTreeCode(String treeCode){
 		if(ZStrUtil.hasNoText(treeCode)) {
 			return Lists.newArrayList();
 		}
 		String paramStr=treeCode+"%";
 		return algorithmConfigItemMapper.selectChildrenByTreeCode(paramStr);
 	}
 	
 	
 	@Transactional(rollbackFor=Exception.class,readOnly=false)
	@Override
	public void setStatusByTreeCode(String treeCode, Byte status){
 		if(ZStrUtil.hasNoText(treeCode)) {
 			return ;
 		}
 		AlgorithmConfigItem item = loadByTreeCode( treeCode).orElseThrow(()->ZAlert.newSLE("未查询到数据"));
 		
 		String paramStr=treeCode+"%";
 		 algorithmConfigItemMapper.updateChildrenStatusByTreeCode(paramStr,status);
 		 //根节点不可删除
 		 if(item.getParentId().longValue()==0L) {
 			algorithmConfigItemMapper.updateStatusByTreeCode(treeCode,Byte.valueOf("1"));
 		 }
 		 
 	}


	@Transactional(rollbackFor=Exception.class)
	@Override
	public void deleteAlgorithmConfigItem(Long id) {
		ZAssert.notNull(id, "请选择要操作的数据");
		algorithmConfigItemMapper.deleteByPrimaryKey(id);
	}
	@Transactional(rollbackFor=Exception.class)
	@Override
	public void setAlgorithmConfigItemStatus(Long id, Byte status) {
		ZAssert.notNull(id, "请选择要操作的数据");
		ZAssert.notNull(status, "状态参数错误");
		if(!Stream.of(new Byte[] {-1,0,1}).anyMatch(val->val.equals(status))) {
			ZAlert.serviceLogicalError("状态参数错误");
		}
		algorithmConfigItemMapper.updateStatus( id,  status) ;
	}
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public DataSet loadAlgorithmConfigItemDataSet(Map<String, Object> params) {
		ParamMap pm=ParamMap.filterParam(params);
		pm.getObj("name").ifPresent(v->pm.updateParam("name", "%"+v+"%"));
		DataSet ds=DataSet.newDS2(algorithmConfigItemMapper.selectListCount(pm), algorithmConfigItemMapper.selectMapListPage(pm));
		return ds;
	}
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<AlgorithmConfigItem> loadByAlgIdAndCode(Long algorithmId,java.lang.String code){
		if(ZStrUtil.hasText(code) && algorithmId!=null){
			return Optional.ofNullable(algorithmConfigItemMapper.selectByAlgIdAndCode(algorithmId,code));
		}
		return Optional.empty();
	}
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public Optional<AlgorithmConfigItem> loadByTreeCode(java.lang.String treeCode){
		if(ZStrUtil.hasText(treeCode)){
			return Optional.ofNullable(algorithmConfigItemMapper.selectByTreeCode(treeCode));
		}
		return Optional.empty();
	}
	
	@Transactional(rollbackFor=Exception.class,readOnly=true)
	@Override
	public List<SelectVo> loadAlgorithmConfigItemSelectVo(String keywords) {
		if(ZStrUtil.hasText(keywords)) {
			
		}
		List<SelectVo> voList=algorithmConfigItemMapper.selectDropList(Byte.valueOf("1"));
		
		return voList==null?Lists.newArrayList():voList;
	}



    
}